package com.server;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Queue;

import com.shared.QueueElement;
import com.shared.SystemMsg;

/**
 * This is the major serve used in the Strangeroid server.
 * By default, it opens a TCP socket and listens on TCP port 5000. This
 * port is configurable by passing in the command line. 
 * 
 * @author jiafanz
 *
 */
public class ChatServer 
{
    // The ServerSocket we will use for accepting new connections
    private ServerSocket            ss;
    
    private Queue<QueueElement>     queue = new LinkedList<QueueElement>();
    private QueueHandler            queueHandler;
    
    /**
     * Constructor of the ChatServer
     * @param port the port that this server listens on.
     * @throws IOException
     */
    public ChatServer(int port) throws IOException
    {
        // listen to the port
        listen(port);
    }
    
    /**
     * Listen on a specific port.
     * @param port port that listens on.
     * @throws IOException if any IOException occurs.
     */
    private void listen(int port) throws IOException
    {
        // Create the ServerSocket
        ss = new ServerSocket(port);
        
        // start the QueueHandler thread
        queueHandler = new QueueHandler(queue);
        
        // tell the world that we are ready to go
        System.out.println("Listening on port: " + port + "...");
        
        // keep accepting connections forever
        while (true)
        {
            // Grab the next incoming connection
            Socket s = ss.accept();
            
            // tell the world that we have got a connection from one client.
            System.out.println("Connection from " + s);
            
            // create an QueueElement
            // Create a DataOutputStream for writing data to the other side
            QueueElement element = new QueueElement();
            element.setSocket(s);
            element.setOutputStream(new DataOutputStream(s.getOutputStream()));
            
            // push an queue element (socket/outputstream) into the queue.
            queue.offer(element);
            
            // tells the client it is connected
            queueHandler.sendMsgToQueueElement(element, SystemMsg.Connected.toString());
            
            // check if there is another pair available
            if (!queueHandler.isPairAvailable())
            {
                queueHandler.sendMsgToQueueElement(element, SystemMsg.NoPair.toString());
            }
        }
    }
    
    
    /**
     * Main routine of the program.
     * @param args
     * Usage: java ChatServer <port>
     * If <port> is not specified, by default, it uses 5000.
     * @throws Exception
     */
    public static void main(String[] args) throws Exception
    {
        int port = 5000;
        
        // Get the port number from the command line
        if (args != null && args.length != 0)
        {
            port = Integer.parseInt(args[0]);
        }
        
        new ChatServer(port);
    }
}
